package cn.mlong.demo.install

import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.SystemInfo
import java.io.BufferedReader
import java.io.InputStreamReader

class InstallApkAction : AnAction("Adb install") {
    private val logger = Logger.getInstance(InstallApkAction::class.java)
    override fun getActionUpdateThread() = ActionUpdateThread.BGT
    override fun actionPerformed(e: AnActionEvent) {
        val project = e.project
        val file = e.getData(CommonDataKeys.VIRTUAL_FILE) ?: run {
            showError(project, "请选择一个APK文件")
            return
        }

        if (!file.name.endsWith(".apk", ignoreCase = true)) {
            showError(project, "请选择APK文件")
            return
        }

        val settings = AdbSettings.instance
        try {
            val command = settings.getFullInstallCommand(file.path)
            logger.info("Executing ADB command: $command")

            val process = if (SystemInfo.isWindows) {
                Runtime.getRuntime().exec(arrayOf("cmd.exe", "/c", command))
            } else {
                Runtime.getRuntime().exec(arrayOf("sh", "-c", command))
            }

            val exitCode = process.waitFor()

            val output = readProcessOutput(process)
            logger.info("ADB command output: $output")

            if (exitCode == 0) {
                Messages.showInfoMessage(
                    project,
                    "APK安装成功\n$output ，请手动启动",
                    "安装成功"
                )
            } else {
                val error = readProcessError(process)
                logger.error("ADB command failed: $error")
                showError(
                    project,
                    "ADB命令执行失败 (exit code $exitCode):\n$error\n\n请检查ADB配置和连接"
                )
            }
        } catch (ex: Exception) {
            logger.error("ADB execution error", ex)
            showError(
                project,
                "执行ADB命令失败: ${ex.message}\n"
            )
        }
    }
    private fun extractPackageNameFromInstallOutput(output: String): String? {
        // 从adb install的输出中提取包名
        val patterns = listOf(
            """Package\s+\[([^\]]+)\]""".toRegex(),
            """package:\s*([^\s]+)""".toRegex(),
            """Success\s*\[([^\]]+)\]""".toRegex()
        )

        for (pattern in patterns) {
            val match = pattern.find(output)
            if (match != null) {
                return match.groupValues[1]
            }
        }
        return null
    }
    private fun getRecentlyInstalledPackage(): String? {
        try {
            val command = "adb shell pm list packages | tail -5" // 获取最后5个包
            val process = if (SystemInfo.isWindows) {
                Runtime.getRuntime().exec(arrayOf("cmd.exe", "/c", command))
            } else {
                Runtime.getRuntime().exec(arrayOf("sh", "-c", command))
            }

            val output = readProcessOutput(process)
            process.waitFor()

            // 提取包名（去掉package:前缀）
            val packages = output.lines()
                .filter { it.startsWith("package:") }
                .map { it.replace("package:", "") }

            return packages.lastOrNull() // 返回最后一个（可能是最新安装的）
        } catch (e: Exception) {
            logger.warn("无法获取已安装包列表: ${e.message}")
            return null
        }
    }
    // 新增方法：从APK文件中提取包名
    private fun extractPackageName(apkPath: String): String? {
        try {
            val command = "aapt dump badging $apkPath | grep package:"
            val process = if (SystemInfo.isWindows) {
                Runtime.getRuntime().exec(arrayOf("cmd.exe", "/c", command))
            } else {
                Runtime.getRuntime().exec(arrayOf("sh", "-c", command))
            }

            val output = readProcessOutput(process)
            process.waitFor()

            // 解析输出，提取包名
            val packagePattern = """package: name='([^']+)'""".toRegex()
            val matchResult = packagePattern.find(output)
            return matchResult?.groupValues?.get(1)
        } catch (e: Exception) {
            logger.warn("Failed to extract package name from APK: ${e.message}")
            return null
        }
    }
    private fun launchApplication(packageName: String, command: String): Boolean {
        try {
            val launchCommand = "${command} shell monkey -p $packageName -c android.intent.category.LAUNCHER 1"
            logger.info("Executing ADB monkey command: $launchCommand")

            val launchProcess = if (SystemInfo.isWindows) {
                Runtime.getRuntime().exec(arrayOf("cmd.exe", "/c", launchCommand))
            } else {
                Runtime.getRuntime().exec(arrayOf("sh", "-c", launchCommand))
            }

            val launchExitCode = launchProcess.waitFor()
            val launchOutput = readProcessOutput(launchProcess)
            val launchError = readProcessError(launchProcess)

            logger.info("ADB launch output: $launchOutput")
            return launchExitCode == 0
        } catch (e: Exception) {
            logger.error("Failed to launch application: ${e.message}")
            return false
        }
    }



    private fun readProcessOutput(process: Process): String {
        return BufferedReader(InputStreamReader(process.inputStream)).use {
            it.readText().trim()
        }
    }

    private fun readProcessError(process: Process): String {
        return BufferedReader(InputStreamReader(process.errorStream)).use {
            it.readText().trim()
        }
    }

    private fun showError(project: Project?, message: String) {
        Messages.showErrorDialog(
            project,
            message,
            "ADB安装错误"
        )
    }

    override fun update(e: AnActionEvent) {
        val file = e.getData(CommonDataKeys.VIRTUAL_FILE)
        e.presentation.isEnabledAndVisible = file != null && file.name.endsWith(".apk", ignoreCase = true)
    }
}